#pragma once
#include "HookJump.h"

/* .NET Namespaces */
using namespace System;
using namespace System::Diagnostics;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;

#define DllExport __declspec( dllexport )

/* Custom Win32 message */
static unsigned int WM_CUSTOM = RegisterWindowMessage("CUSTOM_MESSAGE");

/* Message hook location */
static HHOOK g_messageHookHandle;

/* Structs for memory overwrite hooking 
 * of native methods */
CHookJump g_clsidFromProgIDHook;
CHookJump g_coCreateInstanceHook;

/* Hooked method prototype */
typedef HRESULT (STDMETHODCALLTYPE *CLSID_FROM_PROGID)(LPCOLESTR lpszProgID, LPCLSID lpclsid);
static CLSID_FROM_PROGID g_clsidFromProgID = NULL;

/* Hooked method prototype */
typedef HRESULT (STDMETHODCALLTYPE *CO_CREATE_INSTANCE)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
static CO_CREATE_INSTANCE g_coCreateInstance;

/* A fake GUID to use in one of the hooked methods */
Guid FAKE_CLSID = Guid(L"99C24DD5-D70A-438B-8A42-98424B88AFB8");

/* Helper method to convert .NET Guid to a native _GUID */
_GUID ToGUID( System::Guid& guid ) 
{
   array<Byte>^ guidData = guid.ToByteArray();
   pin_ptr<Byte> data = &(guidData[0]);
   return *(_GUID *)data;
}

DWORD GetHWNDForProcess(DWORD ProcessID, HWND *ProcessHWND);
BOOL CALLBACK FindProcessHWNDThruEnum(HWND hwnd, LPARAM lParam);